
(function () {
    
    ZeroClipboard.setMoviePath( '/media/zeroclipboard/ZeroClipboard10.swf' );

    jQuery.fn.outerHTML = function (s) {
        return (s) ? $(this).before(s).remove() : jQuery("<p>").append($(this).eq(0).clone()).html();
    };
	
    var URL_REGEXP = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/i;
	
    var dec2hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
	
    var today = new Date();
	
    $.extend(CE, {
	
        UTIL: {
            
            init: function(){
                
                // configure the Zero Clipboard plugin.
                this.clip = new ZeroClipboard.Client();
                this.clip.setHandCursor( true );

                //this.clip.addEventListener('load', function (client) {
                //    console.info("Flash movie loaded and ready.");
                //});
                
                this.clip.addEventListener('mouseOver', function (client) {
                    // update the text on mouse over
                    CE.UTIL.clip.setText( window.location + '' );
                });
                
                this.clip.addEventListener('complete', function (client, text) {
                    $.bar({message:"Your theme & location permalink has been copied to your clipboard."});
                });
                
                this.clip.glue( 'd_clip_button', 'd_clip_container' );
            },
        
            // pads a number with zeros on the left, to a specified length.
            zpad: function (num, amount) {
                num = '' + num;
                while (num.length < amount) {
                    num = "0" + num;
                }
                return num;
            },
			
            linkify: function (text) {
                return text.replace(URL_REGEXP, '<a href="$1" target="_blank">$3$4</a>');
            },
			
            color_fade: function (hex, weight) {
                if (hex === 'red') hex = '#ff0000';
                else if (hex === 'green') hex = '#00ff00';
                else if (hex === 'blue') hex = '#0000ff';
                // linearly scale a color by an provided scale factor.
                var out = '';
                carry = 0;
                step = 0;
                for (var i = 0; i < hex.length; i++) {
                    if (indexOf(dec2hex,hex.substr(i,1)) !== - 1) {
                        // average the color with white, based on the weight
                        result = indexOf(dec2hex,hex.substr(i,1)) * weight + (15 * (1.0 - weight));
                        floor = Math.floor(result);
                        carry = result - floor;
                        out += dec2hex[floor];
                        step = 1 - step;
                    } else {
                        out += hex.substr(i,1);
                    }
                }
                return out;
            },
			
            parse_json: function (str) {
                return eval("(" + str + ")");
            },
			
            /* constrain
		     * a bounding function which returns min(max(a,b),c)
		     */
            constrain: function (a, b, c) {
                if (b < a) {
                    return a;
                }
                if (b > c) {
                    return c;
                }
                return b;
            },
			
            date2year: function (date, default_year) {
                if (typeof default_year === 'undefined')
                    default_year = 1970;
                if (!date || date === "None") return default_year;
                year = date.match(/(\d{4})\-(\d{2})\-(\d{2})/);
                return year && year[1] * 1;
            },
			
            /* point
		     * Generates & transforms OpenLayers points
		     */
            point: function (x, y) {
                return new OpenLayers.Geometry.Point(x * 1, y * 1).transform(CE.projectionLatLong, CE.projectionSphericalMercator);
            },
			
            bounds: function (x1, y1, x2, y2) {
                //console.log(x1,y1,x2,y2);
                return new OpenLayers.Bounds(
                x1, y1, x2, y2).transform(CE.projectionLatLong, CE.projectionSphericalMercator);
            },
			
            /**
			 * generic entity description 
			 * opts.show_title - whether to show the title.
			 */
            describe: function (descriptor, opts) {
				opts = opts || {};
                return (opts.show_title ? "<h3>" + descriptor.title + "</h3>" : "") + "<p>" + descriptor.description + "</p>";
            },
			
            today: function () {
                return this.zpad(today.getFullYear(), 2) + "-" + this.zpad(today.getMonth(), 2) + "-" + this.zpad(today.getDate(), 2);
            },
			
            /* generic default dates */
            default_dates: function(entity) {
	            // default dates
	            if (entity.date_start === "None" || !entity.date_start) {
	                entity.date_start = "1970-01-01";
	            }
	            if (entity.date_end === "None" || !entity.date_end) {
	                entity.date_end = "2019-01-01";
	            }
            },
            
	        // Return sorted list of keys
	        // @param obj - composite object to sort.
	        // @param sort_by - attribute of objects to sort by.
	        // @param serializer - key of object method to use for pre-sort serialization.
	        sorted_keys: function(obj, sort_by, serializer) {
	          var lookup = {}, sorted = [], out = [], hash;
	          for(var key in obj) {
	            if (serializer) {
	              hash = obj[key][sort_by][serializer]();
	            } else { // default serializer is the toString method.
	              hash = obj[key][sort_by] + '';
	            }
	            if (typeof lookup[hash] == 'undefined') {
	              lookup[hash] = [];
	            }
	            lookup[hash].push(key);
	          }
	          for (hash in lookup) {
	            sorted.push(hash);
	          }
	
	          sorted.sort();
	          for (var i = 0; i < sorted.length; i++) {
	            for (var j = 0; j < lookup[sorted[i]].length; j++) {
	              out.push(lookup[sorted[i]][j]);
	            }
	          }
	          return out;
	        },
            
            // gets a single entity from an object literal (hash)
            get_one_key: function(o) {
                for (var k in o) {return k;}
            }
        }
    });
    
})();

// This plugin is ridiculously small, so I'm not going to put it in its own file.
(function ($) {

    $.fn.Watermark = function (text, color) {
        if (!color) color = "#aaa";
        return this.each(
        function () {
            var input = $(this);
            var defaultColor = input.css("color");
            clearMessage = function () {
                if (input.val() == text) input.val("");
                input.css("color", defaultColor);
            };
            insertMessage = function () {
                if (input.val().length === 0 || input.val() === text) {
                    input.val(text);
                    input.css("color", color);
                } else input.css("color", defaultColor);
            };
            input.focus(clearMessage);
            input.blur(insertMessage);
            input.change(insertMessage);
            insertMessage();
        });
    };
	
})(jQuery);
